package redis_options

import (
	"context"
	"gitee.com/zaper/service-center-client/service/discover"
	"github.com/go-redis/redis/v8"
	"math/rand"
	"time"
)

type RedisOptions struct {
	redisClient *redis.Client
}

func NewRedisOptions() *RedisOptions {
	instances := discover.GetDiscoverClientManager().GetServiceInfo("redis-service")
	if instances == nil || len(instances) == 0 {
		return nil
	}

	instance := instances[rand.Intn(len(instances))]

	if instance.Endpoints == nil || len(instance.Endpoints) == 0 {
		return nil
	}
	addr := instance.Endpoints[0]

	redisOptionManager := &RedisOptions{
		redisClient: redis.NewClient(&redis.Options{
			Addr:     addr, // Redis服务器地址
			Username: "root",
			Password: "123456", // 无密码（如有密码需填写）
			DB:       0,        // 默认数据库0

			MaxRetries:   3,
			DialTimeout:  5 * time.Second,
			ReadTimeout:  10 * time.Second,
			WriteTimeout: 5 * time.Second,

			PoolSize:     30,
			MinIdleConns: 5,
			IdleTimeout:  30 * time.Second,
		}),
	}

	ctx := context.Background()
	_, err := redisOptionManager.redisClient.Ping(ctx).Result()
	if err != nil {
		return nil
	}
	return redisOptionManager
}

func (redisOptions *RedisOptions) Set(key string, value interface{}) *redis.StatusCmd {
	return redisOptions.redisClient.Set(context.Background(), key, value, 0)
}

func (redisOptions *RedisOptions) TllSet(key string, value interface{}, expiration time.Duration) *redis.StatusCmd {
	return redisOptions.redisClient.Set(context.Background(), key, value, expiration)
}

func (redisOptions *RedisOptions) Get(key string) string {
	rt, err := redisOptions.redisClient.Get(context.Background(), key).Result()
	if err != nil {
		return ""
	}
	return rt
}

func (redisOptions *RedisOptions) HSet(key string, values ...interface{}) *redis.IntCmd {
	return redisOptions.redisClient.HSet(context.Background(), key, values...)
}

func (redisOptions *RedisOptions) HGet(key string, field string) string {
	rt, err := redisOptions.redisClient.HGet(context.Background(), key, field).Result()
	if err != nil {
		return ""
	}
	return rt
}

func (redisOptions *RedisOptions) Expire(key string, expiration time.Duration) bool {
	rt, err := redisOptions.redisClient.Expire(context.Background(), key, expiration).Result()
	if err != nil {
		return false
	}
	return rt
}

func (redisOptions *RedisOptions) SetNx(key string, value interface{}, expiration time.Duration) (bool, error) {
	rt, err := redisOptions.redisClient.SetNX(context.Background(), key, value, expiration).Result()
	if err != nil {
		return false, err
	}
	return rt, nil
}

func (redisOptions *RedisOptions) Eval(script string, keys []string, args ...interface{}) (interface{}, error) {
	rt, err := redisOptions.redisClient.Eval(context.Background(), script, keys, args).Result()
	if err != nil {
		return nil, err
	}
	return rt, nil
}

func (redisOptions *RedisOptions) Close() {
	if redisOptions.redisClient != nil {
		redisOptions.redisClient.Close()
	}
}
